home *** CD-ROM | disk | FTP | other *** search
/ BCI NET / BCI NET Dec 94.iso / archives / telecomm / bbs / tbbs093.lha / Programmer / TechWWF_src / TechWWF.c < prev    next >
C/C++ Source or Header  |  1994-04-07  |  24KB  |  743 lines

  1. #include <TechWWF.h>
  2. #include <WWFData.h>
  3. #include <ctype.h>
  4.  
  5. extern int CutName;
  6.  
  7. const char verstr[] = { "\0$VER: TechWWF " VERSION "  (" __COMMODORE_DATE__ ")" };
  8.  
  9. int nbrk(void) { return(0); }
  10.  
  11. struct MsgPort *TechConPort, *ReplyPort, *RxPort;
  12.  
  13. int NodeNum, CLocked;
  14.  
  15. int TotalAreas;
  16.  
  17. struct Library *RexxSysBase;
  18.  
  19. UBYTE *StrBuf;
  20.  
  21. struct MinList Areas, Files;
  22.  
  23. int NumAreas, NumMsgs;
  24.  
  25. UBYTE *nnode, *UserName;
  26.  
  27. struct CharSet *InCSet, *OutCSet;
  28.  
  29. BPTR DirLock;
  30.  
  31. int RecPos;
  32.  
  33. void AddFile(UBYTE *);
  34. void WriteControl(void);
  35. void PackArchive(void);
  36. void UnArchive(void);
  37. void ProcessReplies(void);
  38.  
  39. struct CharSet *LoadCSet(UBYTE *);
  40. void ConvString(__A0 UBYTE *, __A1 UBYTE *, __A2 UBYTE *);
  41.  
  42. void CRtoLF(__A0 UBYTE *);
  43. void LFtoCR(__A0 UBYTE *);
  44.  
  45. const char nothing[] = { "" };
  46.  
  47. void ProcessReplies(void)
  48. {
  49.     BPTR hdr, txt;
  50.     struct WWFHdrRWF *rwf;
  51.     char *hdrfile, *txtfile;
  52.     struct MemMsg *mmsg;
  53.     struct DateTime *dt;
  54.  
  55.     if(!(rwf = malloc(sizeof(struct WWFHdrRWF))) || !(mmsg = malloc(sizeof(struct MemMsg)))) return();
  56.     if(!(dt = calloc(sizeof(struct DateTime) + 32, 1))) return();
  57.     dt->dat_StrDate = (char *)&dt[1];
  58.     dt->dat_StrTime = &dt->dat_StrDate[16];
  59.     dt->dat_Format = FORMAT_DOS;
  60.     strcpy(StrBuf, OutDir);
  61.     AddPart(StrBuf, "Header.RWF", 256);
  62.     if(hdr = Open(hdrfile = strdup(StrBuf), MODE_OLDFILE)) {
  63.         strcpy(StrBuf, OutDir);
  64.         AddPart(StrBuf, "Text.RWF", 256);
  65.         if(txt = Open(txtfile = strdup(StrBuf), MODE_OLDFILE)) {
  66.             while(FRead(hdr, rwf, sizeof(struct WWFHdrRWF), 1)) {
  67.                 bzero(mmsg, sizeof(struct MemMsg));
  68.                 mmsg->DestZone = rwf->DestZone;
  69.                 mmsg->DestNet = rwf->DestNet;
  70.                 mmsg->DestNode = rwf->DestNode;
  71.                 mmsg->DestPoint = rwf->DestPoint;
  72.                 if(rwf->OrigArea == rwf->Area) mmsg->Original = rwf->OrigNum;
  73.                 if(rwf->Flags & RWFHDR_PRIVATE) mmsg->Bits = MSG_PRIVATE;
  74.                 mmsg->FromUser = UserName;
  75.                 if(InCSet) {
  76.                     mmsg->ToUser = malloc(strlen(rwf->ToUser) + 1);
  77.                     ConvString(rwf->ToUser, mmsg->ToUser, InCSet->CnvFrom);
  78.                     mmsg->Subject = malloc(strlen(rwf->Subject) + 1);
  79.                     ConvString(rwf->Subject, mmsg->Subject, InCSet->CnvFrom);
  80.                     {
  81.                         char *tmp;
  82.  
  83.                         tmp = malloc(rwf->TextLen + 1);
  84.                         tmp[rwf->TextLen] = 0;
  85.                         Seek(txt, rwf->TextPos, OFFSET_BEGINNING);
  86.                         FRead(txt, tmp, 1, rwf->TextLen);
  87.                         mmsg->MsgText = malloc(rwf->TextLen + 1);
  88.                         ConvString(tmp, mmsg->MsgText, InCSet->CnvFrom);
  89.                         free(tmp);
  90.                     }
  91.                 } else {
  92.                     mmsg->ToUser = strdup(rwf->ToUser);
  93.                     mmsg->Subject = strdup(rwf->Subject);
  94.                     mmsg->MsgText = malloc(rwf->TextLen + 1);
  95.                     mmsg->MsgText[rwf->TextLen] = 0;
  96.                     Seek(txt, rwf->TextPos, OFFSET_BEGINNING);
  97.                     FRead(txt, mmsg->MsgText, 1, rwf->TextLen);
  98.                 }
  99.                 LFtoCR(mmsg->MsgText);
  100.                 mmsg->AttFile = nothing;
  101.                 DateStamp(&dt->dat_Stamp);
  102.                 DateToStr(dt);
  103.                 sprintf(mmsg->DateTime, "%-9.9s  %-8.8s", dt->dat_StrDate, dt->dat_StrTime);
  104.                 sprintf(StrBuf, "PostMsgRaw %lx %lu", mmsg, rwf->Area);
  105.                 NumMsgs++;
  106.                 RexxCmd(StrBuf);
  107.                 free(mmsg->ToUser);
  108.                 free(mmsg->Subject);
  109.                 free(mmsg->MsgText);
  110.             }
  111.             Close(txt);
  112.             remove(txtfile);
  113.         } else {
  114.             if(Quiet) RexxCmd("ShowMessage TechWWF Error: Couldn't find Text.RWF");
  115.             else RexxCmd("SendModem \015\012TechWWF Error: Couldn't find Text.RWF");
  116.         }
  117.         Close(hdr);
  118.         remove(hdrfile);
  119.     } else {
  120.         if(Quiet) RexxCmd("ShowMessage TechWWF Error: Couldn't find Header.RWF");
  121.         else RexxCmd("SendModem \015\012TechWWF Error: Couldn't find Header.RWF");
  122.     }
  123. }
  124.  
  125. void UnArchive(void)
  126. {
  127.     UBYTE *nm;
  128.  
  129.     nm = RexxFnc("GetUserPath", nnode, UserName, NULL);
  130.     strcpy(StrBuf, nm);
  131.     free(nm);
  132.     {
  133.         UBYTE Tmp[16];
  134.  
  135.         sprintf(Tmp, "%s.RRF", BBSID);
  136.         AddPart(StrBuf, Tmp, 256);
  137.     }
  138.     nm = strdup(StrBuf);
  139.     sprintf(StrBuf, "%s %s %s/", unpack, nm, OutDir);
  140.     System(StrBuf, NULL);
  141.     remove(nm);
  142.     free(nm);
  143. }
  144.  
  145. UBYTE *aname;
  146.  
  147. void PackArchive(void)
  148. {
  149.     UBYTE *nm;
  150.  
  151.     nm = RexxFnc("GetUserPath", nnode, UserName, NULL);
  152.     strcpy(StrBuf, nm);
  153.     free(nm);
  154.     {
  155.         UBYTE Tmp[16];
  156.  
  157.         sprintf(Tmp, "%s.WWF", BBSID);
  158.         AddPart(StrBuf, Tmp, 256);
  159.     }
  160.     nm = strdup(StrBuf);
  161.     remove(nm);
  162.     UnLock(DirLock);
  163.     DirLock = Lock(OutDir, ACCESS_READ);
  164.     sprintf(StrBuf, "%s %s %s/#?", pack, nm, OutDir);
  165.     System(StrBuf, NULL);
  166.     {
  167.         struct Node *nd;
  168.  
  169.         while(nd = GetHead(&Files)) {
  170.             Remove(nd);
  171.             remove(nd->ln_Name);
  172.             free(nd->ln_Name);
  173.             free(nd);
  174.         }
  175.     }
  176.     aname = nm;
  177. }
  178.  
  179. void AddFile(UBYTE *fname)
  180. {
  181.     struct Node *nd;
  182.  
  183.     nd = calloc(sizeof(struct Node), 1);
  184.     nd->ln_Name = strdup(fname);
  185.     nd->ln_Type = NT_USER;
  186.     AddTail((struct List *)&Files, nd);
  187. }
  188.  
  189. void PackMessages(void)
  190. {
  191.     BPTR datamsg, areahdr, phdr = NULL;
  192.     struct Node *nd;
  193.     struct WWFMsgHdr *hdr;
  194.     struct WWFPersonal *wwfp;
  195.  
  196.     NewList((struct List *)&Files);
  197.     strcpy(StrBuf, OutDir);
  198.     AddPart(StrBuf, "Data.MSG", 256);
  199.     AddFile(StrBuf);
  200.     if(!(datamsg = Open(StrBuf, MODE_NEWFILE))) return();
  201.     hdr = malloc(sizeof(struct WWFMsgHdr));
  202.     wwfp = calloc(sizeof(struct WWFPersonal), 1);
  203.     if(!Quiet) RexxCmd("SendModem \015\012\015\012Packing messages...");
  204.     nd = GetHead(&Areas);
  205.     while(nd) {
  206.         struct AreaCfg *ac = (struct AreaCfg *)nd->ln_Name;
  207.         ULONG HighRead;
  208.  
  209.         {
  210.             UBYTE *rt;
  211.  
  212.             sprintf(StrBuf, "%lu", ac->AreaNr);
  213.             rt = RexxFnc("GetHighRead", nnode, StrBuf, NULL);
  214.             HighRead = strtol(rt, NULL, 0);
  215.             free(rt);
  216.         }
  217.         if((HighRead < (ac->LowMsg - 1)) && (ac->LowMsg > 1)) HighRead = ac->LowMsg - 1;
  218.         if((HighRead < ac->HiMsg) && (ac->HiMsg)) {
  219.             ULONG NumMsg;
  220.  
  221.             areahdr = NULL;
  222.             sprintf(StrBuf, "SendModem \015\012\015\012Area: %s  Messages: %-4lu", ac->Name, (ac->HiMsg - HighRead));
  223.             if(!Quiet) RexxCmd(StrBuf);
  224.             for(NumMsg = HighRead + 1; NumMsg <= ac->HiMsg; NumMsg++) {
  225.                 struct FMsg *fm;
  226.                 struct MemMsg *mmsg;
  227.  
  228.                 if(fm = LoadMsg(ac, NumMsg)) {
  229.                     mmsg = F2MMsg(fm);
  230.                     if((mmsg->Bits & MSG_PRIVATE) && Stricmp(UserName, mmsg->ToUser) && Stricmp(UserName, mmsg->FromUser)) continue;
  231.                     if(!areahdr) {
  232.                         char *tmp;
  233.  
  234.                         sprintf(StrBuf, "%lu.HDR", ac->AreaNr);
  235.                         tmp = strdup(StrBuf);
  236.                         strcpy(StrBuf, OutDir);
  237.                         AddPart(StrBuf, tmp, 256);
  238.                         free(tmp);
  239.                         AddFile(StrBuf);
  240.                         areahdr = Open(StrBuf, MODE_NEWFILE);
  241.                     }
  242.                     if(areahdr) {
  243.                         hdr->MsgNum = mmsg->MsgNum;
  244.                         strncpy(hdr->Date, mmsg->DateTime, 20);
  245.                         hdr->ReplyTo = mmsg->Original;
  246.                         hdr->NextReply = mmsg->NextReply;
  247.                         hdr->OrigZone = mmsg->OrigZone;
  248.                         hdr->OrigNet = mmsg->OrigNet;
  249.                         hdr->OrigNode = mmsg->OrigNode;
  250.                         hdr->OrigPoint = mmsg->OrigPoint;
  251.                         hdr->DestZone = mmsg->DestZone;
  252.                         hdr->DestNet = mmsg->DestNet;
  253.                         hdr->DestNode = mmsg->DestNode;
  254.                         hdr->DestPoint = mmsg->DestPoint;
  255.                         if(mmsg->Bits & MSG_PRIVATE) hdr->Flags = WWFHDR_PRIVATE;
  256.                         else hdr->Flags = 0;
  257.                         if(mmsg->Bits & MSG_RECEIVED) hdr->Flags |= WWFHDR_RECEIVED;
  258.                         hdr->TextPos = Seek(datamsg, 0, OFFSET_CURRENT);
  259.                         CRtoLF(mmsg->MsgText);
  260.                         hdr->TextLen = FWrite(datamsg, mmsg->MsgText, 1, hdr->TextLen = strlen(mmsg->MsgText));
  261.                         bzero(hdr->FromUser, 154);
  262.                         strncpy(hdr->FromUser, mmsg->FromUser, 40);
  263.                         strncpy(hdr->ToUser, mmsg->ToUser, 40);
  264.                         strncpy(hdr->Subject, mmsg->Subject, 74);
  265.                         FWrite(areahdr, hdr, sizeof(struct WWFMsgHdr), 1);
  266.                         NumMsgs++;
  267.                         if(!Stricmp(UserName, mmsg->ToUser)) {
  268.                             if(!phdr) {
  269.                                 strcpy(StrBuf, OutDir);
  270.                                 AddPart(StrBuf, "Personal.HDR", 256);
  271.                                 AddFile(StrBuf);
  272.                                 phdr = Open(StrBuf, MODE_NEWFILE);
  273.                             }
  274.                             if(phdr && wwfp) {
  275.                                 wwfp->AreaNum = ac->AreaNr;
  276.                                 wwfp->MsgNum = hdr->MsgNum;
  277.                                 FWrite(phdr, wwfp, sizeof(struct WWFPersonal), 1);
  278.                             }
  279.                         }
  280.                     }
  281.                     free(mmsg);
  282.                     FreeVec(fm);
  283.                 }
  284.                 if(!Quiet && !((ac->HiMsg - NumMsg) % 5)) {
  285.                     sprintf(StrBuf, "SendModem \033[4D%-4lu", (ac->HiMsg - NumMsg));
  286.                     RexxCmd(StrBuf);
  287.                 }
  288.             }
  289.             if(areahdr) Close(areahdr);
  290.             if(!Quiet) RexxCmd("SendModem \033[4DOK...");
  291.             sprintf(StrBuf, "SetHighRead %lu %lu", ac->AreaNr, ac->HiMsg);
  292.             RexxCmd(StrBuf);
  293.         }
  294.         nd = GetSucc(nd);
  295.     }
  296.     if(datamsg) Close(datamsg);
  297.     if(phdr) Close(phdr);
  298. }
  299.  
  300. void WriteControl(void)
  301. {
  302.     {
  303.     struct InfoBBS *InfoBBS;
  304.     BPTR ctl;
  305.  
  306.     if(InfoBBS = calloc(sizeof(struct InfoBBS), 1)) {
  307.         strncpy(InfoBBS->BBSName, BBSName, 80);
  308.         strncpy(InfoBBS->SysOpName, BBSSysOp, 40);
  309.         if(ForceISO) InfoBBS->Flags |= WWFINFO_ONLYISO;
  310.         InfoBBS->Flags |= 2;
  311.         strncpy(InfoBBS->UserName, UserName, 40);
  312.         {
  313.             char *tmp;
  314.  
  315.             if(UAlias) {
  316.                 if(tmp = RexxFnc("GetUserMisc", nnode, UAlias, NULL)) {
  317.                     strncpy(InfoBBS->UserAlias, tmp, 40);
  318.                     free(tmp);
  319.                 }
  320.             }
  321.             if(UAddress) {
  322.                 if(tmp = RexxFnc("GetUserMisc", nnode, UAddress, NULL)) {
  323.                     strncpy(InfoBBS->UserAddress, tmp, 30);
  324.                     free(tmp);
  325.                 }
  326.             }
  327.             if(UPostCode) {
  328.                 if(tmp = RexxFnc("GetUserMisc", nnode, UPostCode, NULL)) {
  329.                     strncpy(InfoBBS->UserPostalCode, tmp, 10);
  330.                     free(tmp);
  331.                 }
  332.             }
  333.             if(UCity) {
  334.                 if(tmp = RexxFnc("GetUserMisc", nnode, UCity, NULL)) {
  335.                     strncpy(InfoBBS->UserCity, tmp, 30);
  336.                     free(tmp);
  337.                 }
  338.             }
  339.             if(UCountry) {
  340.                 if(tmp = RexxFnc("GetUserMisc", nnode, UCountry, NULL)) {
  341.                     strncpy(InfoBBS->UserCountry, tmp, 30);
  342.                     free(tmp);
  343.                 }
  344.             }
  345.             if(UPhone) {
  346.                 if(tmp = RexxFnc("GetUserMisc", nnode, UPhone, NULL)) {
  347.                     strncpy(InfoBBS->UserPhone, tmp, 20);
  348.                     free(tmp);
  349.                 }
  350.             }
  351.         }
  352.         strncpy(InfoBBS->BBSID, BBSID, 80);
  353.         strcpy(StrBuf, OutDir);
  354.         AddPart(StrBuf, "Info.BBS", 256);
  355.         AddFile(StrBuf);
  356.         if(ctl = Open(StrBuf, MODE_NEWFILE)) {
  357.             FWrite(ctl, InfoBBS, sizeof(struct InfoBBS), 1);
  358.             Close(ctl);
  359.         }
  360.         free(InfoBBS);
  361.     }
  362.     }
  363.     {
  364.         struct AreaIWF *IWF;
  365.         BPTR iwf;
  366.         long Acc = 0, Msk = 0;
  367.  
  368.         {
  369.             char *tmp;
  370.  
  371.             if(tmp = RexxFnc("GetUserAccess", nnode, NULL)) {
  372.                 Acc = strtol(tmp, NULL, 0);
  373.                 free(tmp);
  374.             }
  375.             if(tmp = RexxFnc("GetMask", nnode, NULL)) {
  376.                 Msk = strtol(tmp, NULL, 0);
  377.                 free(tmp);
  378.             }
  379.         }
  380.         if(IWF = malloc(sizeof(struct AreaIWF))) {
  381.             strcpy(StrBuf, OutDir);
  382.             AddPart(StrBuf, "Area.IWF", 256);
  383.             AddFile(StrBuf);
  384.             if(iwf = Open(StrBuf, MODE_NEWFILE)) {
  385.                 struct Node *an;
  386.                 struct AreaCfg *ac;
  387.  
  388.                 an = GetHead(&Areas);
  389.                 while(an) {
  390.                     ac = (struct AreaCfg *)an->ln_Name;
  391.                     IWF->AreaNum = ac->AreaNr;
  392.                     bzero(IWF->AreaName, 34);
  393.                     strncpy(IWF->AreaName, ac->Name, 34);
  394.                     if(!ac->Type) IWF->Flags = WWFAREA_NETMAIL;
  395.                     else if(ac->Type == 1) IWF->Flags = WWFAREA_ECHO;
  396.                     else if(ac->Type == 2) IWF->Flags = WWFAREA_FEEDB;
  397.                     else IWF->Flags = 0;
  398.                     if((Acc >= ac->WriteAcc) && ((Msk & ac->WriteMask) == ac->WriteMask)) IWF->Flags |= WWFAREA_WRITE | WWFAREA_REPLY;
  399.                     FWrite(iwf, IWF, sizeof(struct AreaIWF), 1);
  400.                     an = GetSucc(an);
  401.                 }
  402.                 Close(iwf);
  403.             }
  404.             free(IWF);
  405.         }
  406.     }
  407. }
  408.  
  409. void MakeAreaList(void)
  410. {
  411.     int cc;
  412.  
  413.     NewList((struct List *)&Areas);
  414.     TotalAreas = (int)SendBBSMsg(ID_GETNUMAREAS, NULL);
  415.     NumAreas = 0;
  416.     for(cc = 1; cc <= TotalAreas; cc++) {
  417.         UBYTE *rt;
  418.  
  419.         sprintf(StrBuf, "%lu", cc);
  420.         rt = RexxFnc("GetAreaMode", nnode, StrBuf, NULL);
  421.         if(strtol(rt, NULL, 0)) {
  422.             struct Node *nd;
  423.  
  424.             nd = calloc(sizeof(struct Node), 1);
  425.             nd->ln_Name = (UBYTE *)SendBBSMsg(ID_GETMSGAREA, (APTR)cc);
  426.             nd->ln_Type = NT_USER;
  427.             AddTail((struct List *)&Areas, nd);
  428.             NumAreas++;
  429.         }
  430.         free(rt);
  431.     }
  432. }
  433.  
  434. struct Process *MyProc;
  435.  
  436. void main(int ac, char **av)
  437. {
  438.     onbreak(nbrk);
  439.     MyProc = (struct Process *)FindTask(NULL);
  440.     if(!(StrBuf = malloc(256))) Close_All();
  441.     if(!(ReplyPort = CreateMsgPort())) Close_All();
  442.     if(!(RexxSysBase = OpenLibrary("rexxsyslib.library", 0))) Close_All();
  443.     Forbid();
  444.     TechConPort = FindPort("TechCon_Private");
  445.     RxPort = FindPort("TechCon");
  446.     Permit();
  447.     if(!TechConPort) Close_All();
  448.     SendBBSMsg(ID_INCOPENCOUNT, NULL);
  449.     SendBBSMsg(ID_BEGINMSGH, NULL);
  450.     if(!RxPort) Close_All();
  451.     if(ac != 4) {
  452.         fprintf(stderr, "Usage: %s <node number> <I/O> <config>\n", av[0]);
  453.         Close_All();
  454.     }
  455.     NodeNum = strtol(av[1], NULL, 0);
  456.     {
  457.         UBYTE *PName;
  458.  
  459.         sprintf(StrBuf, "%lu", NodeNum);
  460.         nnode = strdup(StrBuf);
  461.         PName = RexxFnc("Con_LineActive", nnode, NULL);
  462.         if(!strlen(PName)) {
  463.             fprintf(stderr, "Node %lu not active\n", NodeNum);
  464.             Close_All();
  465.         }
  466.         Forbid();
  467.         if(RxPort = FindPort(PName)) {
  468.             RexxCmd("LockCarrier");
  469.             CLocked = 1;
  470.         }
  471.         Permit();
  472.         free(PName);
  473.         if(!RxPort) Close_All();
  474.         UserName = RexxFnc("GetUserName", nnode, NULL);
  475.     }
  476.     {
  477.         BPTR fh;
  478.  
  479.         if(fh = Open(av[3], MODE_OLDFILE)) {
  480.             parsebbscfg(fh);
  481.             Close(fh);
  482.         } else {
  483.             fprintf(stderr, "Couldn't open %s\n", av[3]);
  484.             Close_All();
  485.         }
  486.         if(!BBSName || !BBSSysOp || !BBSID || !OutDir) {
  487.             fprintf(stderr, "Invalid configuration\n");
  488.             if(!Quiet) RexxCmd("SendModem \015\012\015\012Invalid configuration\015\012\015\012");
  489.             Close_All();
  490.         }
  491.         {
  492.             UBYTE *str;
  493.  
  494.             if(str = RexxFnc("GetUserMisc", nnode, "WWFTASKPRI", NULL)) {
  495.                 if(strlen(str)) TaskPri = strtol(str, NULL, 0);
  496.                 free(str);
  497.             }
  498.             if(str = RexxFnc("GetUserMisc", nnode, "WWFARC", NULL)) {
  499.                 if(strlen(str)) pack = str;
  500.                 else free(str);
  501.             }
  502.             if(str = RexxFnc("GetUserMisc", nnode, "WWFUNARC", NULL)) {
  503.                 if(strlen(str)) unpack = str;
  504.                 else free(str);
  505.             }
  506.             if(str = RexxFnc("GetUserMisc", nnode, "WWFASYNC", NULL)) {
  507.                 if(strlen(str)) Quiet = strtol(str, NULL, 0);
  508.                 free(str);
  509.             }
  510.             if(!ForceISO) {
  511.                 if(str = RexxFnc("GetUserMisc", nnode, "WWFINCSET", NULL)) {
  512.                     if(strlen(str)) InCSet = LoadCSet(str);
  513.                     free(str);
  514.                 }
  515.                 if(str = RexxFnc("GetUserMisc", nnode, "WWFOUTCSET", NULL)) {
  516.                     if(strlen(str)) OutCSet = LoadCSet(str);
  517.                     free(str);
  518.                 }
  519.             }
  520.         }
  521.         SetTaskPri((struct Task *)MyProc, TaskPri);
  522.         {
  523.             UBYTE Tmp[30];
  524.  
  525.             sprintf(Tmp, "tWWF_%lx", MyProc);
  526.             strcpy(StrBuf, OutDir);
  527.             AddPart(StrBuf, Tmp, 256);
  528.             free(OutDir);
  529.             OutDir = strdup(StrBuf);
  530.             DirLock = CreateDir(OutDir);
  531.         }
  532.     }
  533.     if(av[2][0] == 'I') {
  534.         if(!Quiet) RexxCmd("SendModem \015\012\015\012Unarchiving replies...");
  535.         UnArchive();
  536.         if(!Quiet) RexxCmd("SendModem \015\012\015\012Processing...");
  537.         ProcessReplies();
  538.         if(NumMsgs) {
  539.             if(!Quiet) sprintf(StrBuf, "SendModem \015\012\015\012Imported %lu messages\015\012\015\012", NumMsgs);
  540.             else sprintf(StrBuf, "ShowMessage TechWWF: Imported %lu messages", NumMsgs);
  541.             RexxCmd(StrBuf);
  542.         } else {
  543.             if(!Quiet) RexxCmd("SendModem \015\012\015\012No messages imported\015\012\015\012");
  544.             else RexxCmd("ShowMessage TechWWF: No messages imported");
  545.         }
  546.     } else if(av[2][0] == 'O') {
  547.         MakeAreaList();
  548.         if(!NumAreas) {
  549.             if(!Quiet) RexxCmd("SendModem \015\012\015\012No areas selected\015\012\015\012");
  550.             Close_All();
  551.         }
  552.         PackMessages();
  553.         WriteControl();
  554.         if(!Quiet) RexxCmd("SendModem \015\012\015\012Archiving messages...");
  555.         PackArchive();
  556.         sprintf(StrBuf, "SendModem \015\012\015\012Packed %lu messages\015\012\015\012", NumMsgs);
  557.         if(!Quiet) RexxCmd(StrBuf);
  558.         else {
  559.             sprintf(StrBuf, "ShowMessage TechWWF: Packed %lu messages\015\012\015\012%s", NumMsgs, DoneString);
  560.             RexxCmd(StrBuf);
  561.             sprintf(StrBuf, "MarkAnyFile %s", aname);
  562.             RexxCmd(StrBuf);
  563.         }
  564.     } else fprintf(stderr, "Unknown command '%s'\n", av[2][0]);
  565.     Close_All();
  566. }
  567.  
  568. void Close_All(void)
  569. {
  570.     if(DirLock) UnLock(DirLock);
  571.     if(OutDir) {
  572.         sprintf(StrBuf, "delete %s all quiet", OutDir);
  573.         System(StrBuf, NULL);
  574.     }
  575.     if(CLocked) RexxCmd("UnLockCarrier");
  576.     if(TechConPort) {
  577.         SendBBSMsg(ID_ENDMSGH, NULL);
  578.         SendBBSMsg(ID_DECOPENCOUNT, NULL);
  579.     }
  580.     if(RexxSysBase) CloseLibrary(RexxSysBase);
  581.     if(ReplyPort) DeleteMsgPort(ReplyPort);
  582.     exit(0);
  583. }
  584.  
  585. void *SendBBSMsg(UWORD ID, void *data)
  586. {
  587.     static struct BBSMsg *sndmsg = NULL;
  588.  
  589.     if(!sndmsg) sndmsg = calloc(sizeof(struct BBSMsg), 1);
  590.     else bzero(sndmsg, sizeof(struct BBSMsg));
  591.     sndmsg->SendingNode = -1;
  592.     sndmsg->ID = ID;
  593.     sndmsg->data = data;
  594.     sndmsg->Msg.mn_ReplyPort = ReplyPort;
  595.     Forbid();
  596.     PutMsg(TechConPort, (struct Message *)sndmsg);
  597.     Permit();
  598.     Wait(1 << ReplyPort->mp_SigBit);
  599.     while(GetMsg(ReplyPort)) ;
  600.     return(sndmsg->result);
  601. }
  602.  
  603. void RexxCmd(UBYTE *arg)
  604. {
  605.     struct RexxMsg *rxm;
  606.  
  607.     if(rxm = CreateRexxMsg(ReplyPort, NULL, NULL)) {
  608.         rxm->rm_Node.mn_Node.ln_Name = "REXX";
  609.         rxm->rm_Action = RXCOMM;
  610.         ARG0(rxm) = CreateArgstring(arg, strlen(arg));
  611.         Forbid();
  612.         PutMsg(RxPort, (struct Message *)rxm);
  613.         Permit();
  614.         Wait(1 << ReplyPort->mp_SigBit);
  615.         while(GetMsg(ReplyPort)) ;
  616.         ClearRexxMsg(rxm, 1);
  617.         DeleteRexxMsg(rxm);
  618.     }
  619. }
  620.  
  621. STRPTR theArgs[16];
  622.  
  623. __stkargs void *RexxFnc(UBYTE *arg, ...)
  624. {
  625.     va_list va;
  626.     UBYTE *res;
  627.     int cc;
  628.  
  629.     va_start(va, arg);
  630.     theArgs[0] = arg;
  631.     for(cc = 1; (cc < 16) && (((ULONG *)va)[cc - 1]); cc++) theArgs[cc] = (APTR)((ULONG *)va)[cc - 1];
  632.     if(cc < 16) theArgs[cc] = NULL;
  633.     res = DoRxFnc(theArgs);
  634.     va_end(va);
  635.     return(res);
  636. }
  637.  
  638. void *DoRxFnc(UBYTE **arg)
  639. {
  640.     struct RexxMsg *rxm;
  641.     UBYTE *res;
  642.  
  643.     res = strdup("");
  644.     if(rxm = CreateRexxMsg(ReplyPort, NULL, NULL)) {
  645.         int cc;
  646.  
  647.         rxm->rm_Node.mn_Node.ln_Name = "REXX";
  648.         rxm->rm_Action = RXFUNC | RXFF_RESULT;
  649.         for(cc = 0; (arg[cc]) && (cc < 16); cc++) rxm->rm_Args[cc] = CreateArgstring(arg[cc], strlen(arg[cc]));
  650.         rxm->rm_Action |= (cc - 1) & 0xf;
  651.         Forbid();
  652.         PutMsg(RxPort, (struct Message *)rxm);
  653.         Permit();
  654.         Wait(1 << ReplyPort->mp_SigBit);
  655.         while(GetMsg(ReplyPort)) ;
  656.         if(!rxm->rm_Result1) {
  657.             if(rxm->rm_Result2) {
  658.                 free(res);
  659.                 res = strdup((char *)rxm->rm_Result2);
  660.                 DeleteArgstring((UBYTE *)rxm->rm_Result2);
  661.             }
  662.         }
  663.         ClearRexxMsg(rxm, 1);
  664.         DeleteRexxMsg(rxm);
  665.     }
  666.     return(res);
  667. }
  668.  
  669. void CRLFtoEOS(char *);
  670.  
  671. void CRLFtoEOS(char *s)
  672. {
  673.     while(*s && (*s != 10) && (*s != 13)) s++;
  674.     *s = 0;
  675. }
  676.  
  677. void parsebbscfg(BPTR cfh)
  678. {
  679.     UBYTE *buf, *bpos;
  680.  
  681.     buf = calloc(1, 256);
  682.     while(bpos = FGets(cfh, buf, 256)) {
  683.         CRLFtoEOS(bpos);
  684.         while(*bpos == ' ' || *bpos == 9) bpos++;
  685.         if(*bpos == '>') System(++bpos, NULL);
  686.         else if(*bpos != ';' && *bpos != '#' && *bpos) {
  687.             int cc = 0;
  688.             UBYTE *scan;
  689.  
  690.             scan = bpos;
  691.             while(*scan && *scan != ' ' && *scan != 9) scan++;
  692.             if(*scan) *scan++ = 0;
  693.             while(CfgList[cc].id) {
  694.                 if(!(Stricmp(bpos, CfgList[cc].id))) {
  695.                     if(CfgList[cc].val >= 0) *CfgList[cc].var = CfgList[cc].val;
  696.                     else {
  697.                         bpos = scan;
  698.                         while(*bpos == ' ' || *bpos == 9) bpos++;
  699.                         if(*bpos) switch(CfgList[cc].val) {
  700.                             case -1:
  701.                                 *CfgList[cc].var = strtol(bpos, NULL, 0);
  702.                                 break;
  703.                             case -2:
  704.                                 if(*bpos != '"') *CfgList[cc].var = strdup(bpos);
  705.                                 else {
  706.                                     UBYTE *bscan;
  707.  
  708.                                     bscan = ++bpos;
  709.                                     while(*bscan != '"' && *bscan) bscan++;
  710.                                     *bscan = 0;
  711.                                     *CfgList[cc].var = strdup(bpos);
  712.                                 }
  713.                         }
  714.                     }
  715.                     break;
  716.                 }
  717.                 cc++;
  718.             }
  719.         }
  720.     }
  721.     free(buf);
  722. }
  723.  
  724. struct CharSet *LoadCSet(UBYTE *Name)
  725. {
  726.     struct CharSet *ncset;
  727.     BPTR csfh;
  728.  
  729.     ncset = NULL;
  730.     sprintf(StrBuf, "%s.DAT", Name);
  731.     if(csfh = Open(StrBuf, MODE_OLDFILE)) {
  732.         ncset = malloc(sizeof(struct CharSet));
  733.         ncset->CnvFrom = malloc(512);
  734.         ncset->CnvTo = &(ncset->CnvFrom[256]);
  735.         FRead(csfh, ncset->CnvFrom, 256, 2);
  736.         ncset->Name = strdup(Name);
  737.         CRLFtoEOS(FGets(csfh, StrBuf, 256));
  738.         ncset->Extension = strdup(StrBuf);
  739.         Close(csfh);
  740.     }
  741.     return(ncset);
  742. }
  743.